package com.google.code.coma.gui.space;

import com.google.code.coma.domain.Part;
import com.google.code.coma.gui.DataProvider;
import com.google.code.coma.space.SelectAllSelectorCallback;
import com.google.code.coma.space.SpaceSelector;
import com.google.code.coma.space.util.SpaceManager;
import com.sun.deploy.uitoolkit.impl.fx.FXWindow;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ListView;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mozartspaces.capi3.Coordinator;
import org.mozartspaces.capi3.FifoCoordinator;
import org.mozartspaces.core.*;
import org.mozartspaces.notifications.Notification;
import org.mozartspaces.notifications.NotificationListener;
import org.mozartspaces.notifications.NotificationManager;
import org.mozartspaces.notifications.Operation;

import java.io.Serializable;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Dominik Strasser, dominikstr@gmail.com
 */
public class SpacePartDataProvider extends AbstractSpaceDataProvider<Part> {
	private static final Log log = LogFactory.getLog(SpacePartDataProvider.class);

	public SpacePartDataProvider(String spaceURI, String container) {
		super(spaceURI, container);
	}

	@Override
	public void bind(final ListView<Part> partListView) {
		partListView.setItems(data);
		try {
			data.addAll(capi.read(containerReference, new SpaceSelector(new SelectAllSelectorCallback()), 1000, null).toArray(new Part[]{}));
		} catch (MzsCoreException e) {
			//nothing to do here
		}
		NotificationManager notifManager = new NotificationManager(core);
		try {
			notifManager.createNotification(containerReference, new NotificationListener() {
				@Override
				public void entryOperationFinished(Notification source, Operation operation, final List<? extends Serializable> entries) {
					if (operation == Operation.WRITE) {
						Platform.runLater(new Runnable() {
							@Override
							public void run() {
								data.addAll(getParts(entries));
							}
						});
					} else if (operation == Operation.TAKE || operation == Operation.DELETE) {
						Platform.runLater(new Runnable() {
							@Override
							public void run() {
								data.removeAll(entries);								
							}
						});
					}
				}

				private List<Part> getParts(List<? extends Serializable> entries) {
					List<Part> parts = new ArrayList<Part>();
					for (Serializable e : entries) {
						//Who the fuck designed this API??? Why serilizable if it has to be an entry according to documentation?
						if (e instanceof Entry) {
							if (((Entry) e).getValue() instanceof Part) {
								parts.add((Part) ((Entry) e).getValue());
							}
						}
					}
					return parts;
				}
			}, Operation.WRITE, Operation.TAKE, Operation.DELETE);
		} catch (Exception e) {
			log.error("Unable to create notification", e);
		}
	}
}
